package com.seanLab.service;

/**
 * Created by ailly on 17-8-26.
 */

import com.seanLab.configuration.ModelConfig;
import com.seanLab.domain.*;
import com.seanLab.dto.EditorArticleDto;
import com.seanLab.dto.SuggestArticleKeywordsDto;
import com.seanLab.dto.SuggestModelArticleDto;
import com.seanLab.repository.ArticleRepo;
import com.seanLab.repository.ImageRepo;
import com.seanLab.tool.data.DataExtractor;
import com.seanLab.tool.TagSuggestor;
import com.seanLab.util.TopicPair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;

@Service
public class ArticleService {
    @Autowired
    private ArticleRepo articleRepo;

    @Autowired
    private ImageRepo imageRepo;

    @Autowired
    private TagSuggestor tagSuggestor;

    @Autowired
    private ModelConfig modelConfig;

    @PostConstruct
    public void init() {
//        StaticModelProperties.ModelPath = modelConfig.getModelPath();
//        StaticModelProperties.SegementModelPath = modelConfig.getSegementModelPath();
//        StaticModelProperties.StopwordsPath = modelConfig.getStopwordsPath();
        this.tagSuggestor.loadModel(modelConfig.getModelPath());
        this.tagSuggestor.loadLdaModel(modelConfig.getLdaModelPath());
//        this.tagSuggestor.loadLdaModel(StaticModelProperties.MyLDAModelPath);
    }

    public Body insertArticle(EditorArticleDto editorArticleDto) {
        //articleRepo.deleteAll();
        //imageRepo.deleteAll();

        //校验数据完整性
        if (isValid(editorArticleDto) ) {
            // transfer editorArticle to article
            Article transArticle_raw = null;
            transArticle_raw = mapArticles(editorArticleDto);

            //插入未打标签的图片 (已经包括将imgID添加到Article中的操作)
            List<Image> transImageList_raw = getImageCollectionFormArticle(transArticle_raw);

            if (transImageList_raw != null) {
                //this.imageDao.insertImageCollection(transImageList_raw);
                this.imageRepo.save(transImageList_raw);
                //插入文章
                //this.articleDao.insertArticle(transArticle_raw);
                this.articleRepo.save(transArticle_raw);

                //抽取文章及图片标签
                Article transArticle_keyword = this.extractKeywordsFromArticle(transArticle_raw);
                List<Image> transImageList_tag = this.extractImgTagsFromArticle(transArticle_raw, transImageList_raw);

                // 抽取文章主题
//                List<Double> tmp_topics = new ArrayList<>();
                List<Double> tmp_topics = this.tagSuggestor.doTopics(transArticle_raw.getContent());

                //计算top主题
                List<Integer> tmp_topTopics = TopicPair.getTopTopics(tmp_topics);

                //更新文章主题
                transArticle_keyword.setArticleTopic(tmp_topics);

                //更新图片主题
                for (Image i : transImageList_tag) {
                    i.setImgTopic(tmp_topics);
                    i.setTopTopics(tmp_topTopics);
                }

                //更新图片
                this.imageRepo.save(transImageList_tag);

                //更新article
                this.articleRepo.save(transArticle_keyword);

            } else {

            }
            return Body.getResponseBody(0);
        }
        return Body.getResponseBody(1);
    }

    private Article mapArticles (EditorArticleDto editorArticleDto){
        Article tmpArticle_mapFromEditorArticle = new Article();
        tmpArticle_mapFromEditorArticle.setArticleID("articleID-" + UUID.randomUUID().toString());
        //tmpArticle_mapFromEditorArticle.setArticleID("1000");

        // 映射能直接使用的属性
        tmpArticle_mapFromEditorArticle.setTypes(editorArticleDto.getTypes());
        tmpArticle_mapFromEditorArticle.setSource(editorArticleDto.getSource());
        tmpArticle_mapFromEditorArticle.setChannel(editorArticleDto.getChannel());
        tmpArticle_mapFromEditorArticle.setTags(editorArticleDto.getTags());
        tmpArticle_mapFromEditorArticle.setUrl(editorArticleDto.getUrl());
        tmpArticle_mapFromEditorArticle.setTitle(editorArticleDto.getTitle());
        tmpArticle_mapFromEditorArticle.setCode(editorArticleDto.getContent());

        // 处理不能直接使用的属性
        tmpArticle_mapFromEditorArticle.setCategory(DataExtractor.getCategoryFromArticle(editorArticleDto.getCategory()));
        tmpArticle_mapFromEditorArticle.setContent(DataExtractor.getContentFormArticle(editorArticleDto.getContent()));

        return tmpArticle_mapFromEditorArticle;
    }


    //此方法负责图片的下载
    private List<Image> getImageCollectionFormArticle(Article article) {
        //使用DataExtractor从文章html中抽取图片
        //功能：抽取图片，并过滤，下载，返回最终的干净的图片列表，注意，此处图片列表为 ArrayList<Image>，

        List<Image> tmpImgList = DataExtractor.getImgList(article.getCode(), article.getArticleID());
        //抽取imgList中的imgID
        List<String> tmpImgID = new ArrayList<String>();
        for (Image img : tmpImgList) {
            tmpImgID.add(img.getImgID());
        }

        //更新article的imgList
        article.setImgID(tmpImgID);

        return tmpImgList;
    }

    private Article extractKeywordsFromArticle(Article article) {
        Article tmpArticle = article;
        //TagSuggestor应返回该文章对应的关键词. e.g., articleTagList
        TagSuggestor ts = this.tagSuggestor;
        SuggestModelArticleDto suggestModelArticleDto = DataExtractor.extractModelArticleWithoutImgsFromArticle(article);
        List<SuggestArticleKeywordsDto> keywords = ts.doKeyword(suggestModelArticleDto);

        tmpArticle.setKeywords(keywords);
        return tmpArticle;
    }

    private List<Image> extractImgTagsFromArticle(Article article, List<Image> imageList) {
        List<Image> tmpImgList = new ArrayList<Image>(imageList);
        //抽取图片关键词

        TagSuggestor ts = this.tagSuggestor;
        SuggestModelArticleDto suggestModelArticleDto = DataExtractor.extractModelArticleFromArticle(article, imageList);
        List<List<TagInfo>> articleTagList = ts.doTag(suggestModelArticleDto);


        for (Image tmpImg : tmpImgList) {
            //设置图片关键词
            int index = tmpImgList.indexOf(tmpImg);
            tmpImg.setImgTagList(articleTagList.get(index));

        }
        return tmpImgList;
    }

    private boolean isValid(EditorArticleDto editorArticleDto) {
        return true;
    }


    public Collection<Article> getAllArticles() {
        return this.articleRepo.findAll();
    }

}
